package org.springblade.modules.serial;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.util.CharsetUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@ChannelHandler.Sharable
public class HeartbeatHandler extends ChannelInboundHandlerAdapter {

    private static final Logger logger = LoggerFactory.getLogger(HeartbeatHandler.class);

    // 心跳响应消息
    private static final ByteBuf HEARTBEAT_RESPONSE = Unpooled.unreleasableBuffer(
            Unpooled.copiedBuffer("HEARTBEAT_RESPONSE\n", CharsetUtil.UTF_8));

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if (evt instanceof IdleStateEvent) {
            IdleStateEvent e = (IdleStateEvent) evt;
            switch (e.state()) {
                case READER_IDLE:
                    handleReaderIdle(ctx);
                    break;
                case WRITER_IDLE:
                    handleWriterIdle(ctx);
                    break;
                case ALL_IDLE:
                    handleAllIdle(ctx);
                    break;
                default:
                    break;
            }
        }
    }

    private void handleReaderIdle(ChannelHandlerContext ctx) {
        logger.info("--- 客户端 {} 读超时，关闭连接 ---", ctx.channel().remoteAddress());
//        ctx.close();
    }

    private void handleWriterIdle(ChannelHandlerContext ctx) {
        logger.info("--- 写超时 ---");
		ctx.close();
    }

    private void handleAllIdle(ChannelHandlerContext ctx) {
        logger.info("--- 所有操作超时 ---");
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        // 如果是心跳请求，则返回响应
        if (msg instanceof String && ((String) msg).equals("HEARTBEAT_REQUEST")) {
            logger.info("收到心跳请求 from {}", ctx.channel().remoteAddress());
            ctx.writeAndFlush(HEARTBEAT_RESPONSE.duplicate());
            return;
        }

        // 不是心跳请求，传递给下一个handler
        super.channelRead(ctx, msg);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        logger.error("心跳处理器异常", cause);
        ctx.close();
    }
}
